import './popover.scss';
import React, { ClassicComponent, FunctionComponent } from 'react';

interface PopoverProps {
    show: boolean;
    position: {left: number, top: number, triangle: 'bottom' | 'top'};
    width?: string | number;
    children?: ClassicComponent | FunctionComponent | JSX.Element | null;
}
interface PopoverState {
    enter: boolean;
}
class Popover extends React.Component<PopoverProps> {
    state: PopoverState
    constructor (props: PopoverProps = { show: false, position: { left: 0, top: 0, triangle: 'top' }, width: 150, children: null }) {
        super(props);
        this.state = { enter: false };
    }
    /** 处理鼠标离开事件 */
    handleEnter () {
        if (this.state.enter) {
            this.setState({ enter: false });
            this.setState({ showPopover: false });
        } else {
            this.setState({ enter: true });
        }
    }

    shouldComponentUpdate (nextProps: Readonly<PopoverProps>, nextState: Readonly<PopoverState>, nextContext: any): boolean {
        const stateNew = (nextProps.show || nextState.enter);
        const stateOld = (this.props.show || this.state.enter);
        const { left: nLeft, top: nTop } = nextProps.position;
        const { left, top } = this.props.position;
        if (Math.floor(left) !== Math.floor(nLeft) || Math.floor(top) !== Math.floor(nTop)) {
            return true;
        }
        if (stateNew && stateOld) {
            return false;
        } else if (!nextProps.show && nextState.enter !== this.state.enter) {
            return true;
        }

        return true;
    }

    render () {
        const { show, position, width, children } = this.props;
        /** 获取三角形位置 */
        const getTrianglePosition = () => {
            if (position.triangle === 'top') {
                return { top: '15px' };
            }
            return { bottom: '15px' };
        };
        return (<div
            style={{
                transformOrigin: position.triangle === 'top' ? 'top left' : 'bottom left',
                left: `${position.left}px`,
                top: `${position.top}px`,
            }}
            className={`popover-container ${(show || this.state.enter) ? 'popover-show' : 'popover-hidden'}`}
            onMouseEnter={this.handleEnter.bind(this)}
            onMouseLeave={this.handleEnter.bind(this)}
        >
            <div
                className={'popover popover-border'}
                style={
                    { width: typeof width === 'number' ? `${width}px` : width }
                }>
                <div className="popover-triangle" style={getTrianglePosition()}></div>
                {children ? children : ''}
            </div>
        </div>);
    }
}

export default Popover;
